<template>
  <div>
    <div
      ref="myPage"
      @click="isShowNodeMenuPanel = false;isShowInfo=false"
     
      style="margin-top: 0px; width: calc(100% - 10px); height: calc(100vh)"
    >
      <RelationGraph ref="graphRef" :options="graphOptions" 
      :on-node-click="onNodeClick"
      :on-canvas-click="onCanvasClick">
        <template #node="{ node }">
          <div  class="my-node-1"  style="height: 100%;"  @click="showNodeMenus(node, $event)"
          @contextmenu.prevent.stop="showNodeMenus(node, $event)">
          
              <div class="my-node-style" :style="{ 'background-image': 'url(http://localhost:805/photo/' + node.id + '.jpg)', }" ></div>
           
            <div class="my-node-text" :style="{ color: node.color }">
          
          {{ node.text }}
        </div>
      </div>
         
        </template>
        <template #graph-plug>
          <div style=" position: absolute; z-index: 700; left: 20px; top: 20px; height: 50px; padding-top: 6px; padding-left: 30px; padding-right: 30px; border: #efefef solid 1px; color: #555555; border-radius: 10px; background-color: rgba(255, 255, 255, 0.79); font-size: 12px; " >
            <div style=""> <el-input placeholder="请输入节点内容" v-model="searchval" class="input-with-select" >
                <el-button @click="search()" slot="append" icon="el-icon-search" ></el-button>
              </el-input>
            </div>
          </div>

          <div
            v-show="isShowInfo"
            class="c-my-panel"
            style="width: 200px"
          >
            <el-card :body-style="{ padding: '0px' }">
              <img v-if="currentNode.data&&currentNode.data.img" style="width: 100%;"
                :src="currentNodeimageUrl" class="image"
              />
              <div style="padding: 14px">
                <span v-if="currentNode.data">{{currentNode.data.info}}</span>
                <!-- <div class="bottom clearfix">
                  <time class="time">{{ currentDate }}</time>
                   <el-button type="text" class="button">操作按钮</el-button> 
                </div> -->
              </div>
            </el-card>
          </div>
        </template>
      </RelationGraph>
    </div>

    <div
      v-show="isShowNodeMenuPanel"
      :style="{ left: nodeMenuPanelPosition.x + 'px', top: nodeMenuPanelPosition.y + 'px', }"
      style=" z-index: 999; padding: 10px; background-color: #ffffff; border: #eeeeee solid 1px; box-shadow: 0px 0px 8px #cccccc; position: absolute; border-radius: 10px; "
    >
      <div style=" line-height: 25px; padding-left: 10px; color: #888888; font-size: 12px; " > 对这个节点进行操作： </div>
      <div class="c-node-menu-item" @click.stop="doAction('1')">
        查看详情
      </div>
      <div class="c-node-menu-item" @click.stop="doAction('2')">展开此节点</div>
      <div class="c-node-menu-item" @click.stop="doAction('操作1')">操作3</div>
      <div class="c-node-menu-item" @click.stop="doAction('操作1')">操作4</div>
    </div>
  </div>
</template>

<script>
// 如果您没有在main.js文件中使用Vue.use(RelationGraph); 就需要使用下面这一行代码来引入relation-graph
//import RelationGraph from 'relation-graph';
import { init } from "echarts";
import demoData from "./Demo4AdvDataFilterData";
const graphOptions = {
  debug: false,
  defaultNodeBorderWidth: 0,
  defaultNodeColor: "rgba(238, 178, 94, 1)",
  allowSwitchLineShape: true,
  allowSwitchJunctionPoint: true,
  defaultLineShape: 1,
  moveToCenterWhenRefresh: false,
  layout: {
    label: "自动布局",
    layoutName: "force",
    layoutClassName: "seeks-layout-force",
    maxLayoutTimes:"500",
   
  },
  defaultJunctionPoint: "border",

  // 这里可以参考"Graph 图谱"中的参数进行设置
};
export default {
  name: "RelationGraphDemo",
  components: {}, // 如果您没有在main.js文件中使用Vue.use(RelationGraph); 就需要在这里注册：components: { RelationGraph }
  data() {
    return {
      isShowInfo: false,
      isShowCodePanel: false,
      isShowNodeMenuPanel: false,
      isShowNodeTipsPanel: false,
      nodeMenuPanelPosition: { x: 0, y: 0 },
      currentNode: {},
      currentNodeimageUrl:"",
      searchval: "贾宝玉",
      datalist: {
        nodes: [],
        // 边集
        lines: [],
      },
      protocol: "bolt",
      host: "172.16.218.125",
      port: 7687,
      username: "neo4j",
      password: "123456",
      g_loading: true,
      demoname: "---",
      checked_sex: "",
      checked_isgoodman: "",
      rel_checkList: [ "师生", "上下级", "亲戚", "情人", "朋友", "夫妻", "勾结", "腐化", "举报", ],
      all_rel_type: ["师生", "上下级", "亲戚", "情人", "朋友", "夫妻","勾结","腐化", "举报", ],
      graphOptions,
    };
  },
  created() {},
  mounted() {
    this.initneo4j();
    //this.setGraphData();
  },
  methods: {
    connect() {
      return this.$neo4j
        .connect(
          this.protocol,
          this.host,
          this.port,
          this.username,
          this.password
        )
        .then((driver) => {
          // Update the context of your app
        });
    },
    search() {
      this.initneo4j();
    },
    onNodeCollapse(node, e) {
      this.$refs.graphRef.refresh();
    },
    loadChildNodesFromRemoteServer(){
         
    },
    // 通过onNodeExpand事件监听节点的展开事件，在被展开的时候有选择的去从后台获取数据，如果已经从后台加载过数据，则让当前图谱根据当前的节点重新布局
    onNodeExpand(node, e) {
      console.log("onNodeExpand:", node);
      
      this.loadChildNodesFromRemoteServer(node, (new_data) => {
        this.g_loading = false;
        this.$refs.graphRef
          .getInstance()
          .appendJsonData(new_data, (graphInstance) => {
            // 这些写上当图谱初始化完成后需要执行的代码
          });
      });
    },
    onNodeClick(nodeObject, $event) {
      console.log('onNodeClick:', nodeObject);
      const allChildIds = this.deepGeAlltChildIds(nodeObject);
      const graphInstance = this.$refs.graphRef.getInstance();
      for (const node of graphInstance.getNodes()) {
        if (allChildIds.includes(node.id)) {
          node.opacity = 1;
          node.color = 'rgb(116,2,173)';
        } else {
          node.opacity = 0.1;
          node.color = undefined;
        }
      }
      for (const link of graphInstance.getLinks()) {
        if (allChildIds.includes(link.fromNode.id) && allChildIds.includes(link.toNode.id)) {
          link.relations.forEach(line => {
            line.color = 'rgb(116,2,173)';
          })
        } else {
          link.relations.forEach(line => {
            line.color = '';
          })
        }
      }
    },
    deepGeAlltChildIds(node, ids=[]) {
      if (ids.includes(node.id)) return;
      ids.push(node.id);
      for (const cNode of node.lot.childs) {
        this.deepGeAlltChildIds(cNode, ids);
      }
      return ids;
    },

    showNodeTips(nodeObject, $event) {
      this.currentNode = nodeObject;
      const _base_position = this.$refs.myPage.getBoundingClientRect();
      console.log(
        "showNodeMenus:",
        $event.clientX,
        $event.clientY,
        _base_position
      );
      this.isShowNodeTipsPanel = true;
      this.nodeMenuPanelPosition.x = $event.clientX - _base_position.x + 10;
      this.nodeMenuPanelPosition.y = $event.clientY - _base_position.y + 10;
    },
    hideNodeTips(nodeObject, $event) {
      this.isShowNodeTipsPanel = false;
    },
    onCanvasClick($event) {
      console.log('onCanvasClick:');
      const graphInstance = this.$refs.graphRef.getInstance();
      for (const node of graphInstance.getNodes()) {
        node.opacity = 1;
        node.color = undefined;
      }
      for (const link of graphInstance.getLinks()) {
        link.relations.forEach(line => {
          line.color = undefined;
        })
      }
    },
    loadChildNodesFromRemoteServer(nodetext,callback){
     
       var cypher = `match p=(n)<-[]->(m) where n.name='${nodetext}'  return  p `;
        this.$neo4j
        .run(cypher) .then((res) => {
          console.log("555", res);
          let records = res.records;
          let nodes = new Set();
           let newnodesRelation = [];
          for (let i = 0; i < records.length; i++) {
            nodes.add({
              id: records[i]._fields[0].segments[0].start.properties.name,
              text: records[i]._fields[0].segments[0].start.properties.name,
              width:records[i]._fields[0].segments[0].start.properties.value,
              height:records[i]._fields[0].segments[0].start.properties.value,
              data: {
                info: records[i]._fields[0].segments[0].start.properties.info,
                img: records[i]._fields[0].segments[0].start.properties.image,
              },
            });
            nodes.add({
              id: records[i]._fields[0].segments[0].end.properties.name,
              text: records[i]._fields[0].segments[0].end.properties.name,
              width:records[i]._fields[0].segments[0].end.properties.value,
              height:records[i]._fields[0].segments[0].end.properties.value,
              data: {
                info: records[i]._fields[0].segments[0].end.properties.info,
                img: records[i]._fields[0].segments[0].end.properties.image,
              },
            });
            newnodesRelation.push({
              from: records[i]._fields[0].segments[0].start.properties.name,
              to: records[i]._fields[0].segments[0].end.properties.name,
              text: records[i]._fields[0].segments[0].relationship.type,
            });
          }
        
          var bb = [];
          bb = [...nodes];
          console.log("新增-bb", bb);
          var aa = [];
          this.echartsData = [];
          aa = Array.from(new Set(bb.map((item) => JSON.stringify(item)))).map(
            (item) => JSON.parse(item)
          );
          console.log("新增-node", aa);
          aa.forEach((e) => {
            this.echartsData.push({
              name: e.name,
            });
          });
          var  cc={ nodes: [],
        // 边集
        lines: []};
        cc.lines=newnodesRelation;
        cc.nodes=aa
          callback(cc)
         
        })
        .then(() => {});
    },

    initneo4j() {
      this.connect();
      let cypher = `match p=(n)-[]->(m)  return  p `;
      if (this.searchval) {
        cypher = `match p=(n)-[]->(m) where n.name='${this.searchval}'  return  p `;
      }

      this.$neo4j
        .run(cypher)
        .then((res) => {
          console.log("555", res);
          let records = res.records;
          let nodes = new Set();
          this.nodesRelation = [];
          for (let i = 0; i < records.length; i++) {
            nodes.add({
              id: records[i]._fields[0].segments[0].start.properties.name,
              text: records[i]._fields[0].segments[0].start.properties.name,
              width:records[i]._fields[0].segments[0].start.properties.value*3,
              height:records[i]._fields[0].segments[0].start.properties.value*3,
              data: {
                info: records[i]._fields[0].segments[0].start.properties.info,
                img: records[i]._fields[0].segments[0].start.properties.image,
              },
            });
            nodes.add({
              id: records[i]._fields[0].segments[0].end.properties.name,
              text: records[i]._fields[0].segments[0].end.properties.name,
              width:records[i]._fields[0].segments[0].end.properties.value*3,
              height:records[i]._fields[0].segments[0].end.properties.value*3,
              data: {
                info: records[i]._fields[0].segments[0].end.properties.info,
                img: records[i]._fields[0].segments[0].end.properties.image,
              },
            });
            this.nodesRelation.push({
              from: records[i]._fields[0].segments[0].start.properties.name,
              to: records[i]._fields[0].segments[0].end.properties.name,
              text: records[i]._fields[0].segments[0].relationship.type,
            });
          }
          this.datalist.lines = this.nodesRelation;
          console.log("this.nodesRelation", this.nodesRelation);
          var bb = [];
          bb = [...nodes];
          console.log("bb", bb);
          var aa = [];
          this.echartsData = [];
          aa = Array.from(new Set(bb.map((item) => JSON.stringify(item)))).map(
            (item) => JSON.parse(item)
          );
          console.log("node", aa);
          aa.forEach((e) => {
            this.echartsData.push({
              name: e.name,
            });
          });

          this.datalist.nodes = aa;
          this.setGraphData();
        })
        .then(() => {});
    },

    setGraphData() {
      //console.log("4444",demoData)
      const __graph_json_data = this.datalist;
      console.log("rtrt", this.datalist);

      this.$refs.graphRef.setJsonData(__graph_json_data, (graphInstance) => {
        // 这些写上当图谱初始化完成后需要执行的代码
      });
    },
    showNodeMenus(nodeObject, $event) {
      this.currentNode = nodeObject;
      const _base_position = this.$refs.myPage.getBoundingClientRect();
      console.log("showNodeMenus:", $event, _base_position);
      this.isShowNodeMenuPanel = true;
      this.nodeMenuPanelPosition.x = $event.clientX - _base_position.x;
      this.nodeMenuPanelPosition.y = $event.clientY - _base_position.y;
    },
    doAction(actionName) {
      // this.$notify({
      //   title: "提示",
      //   message: "对节点【" + this.currentNode.text + "】进行了：" + actionName,
      //   type: "success",
      // });
      switch(actionName){
        case "1":
          console.log("ttt",this.currentNode)
        this.currentNodeimageUrl=`http://localhost:805/photo/${this.currentNode.id}.jpg`;
      this.isShowInfo=true;
      this.isShowNodeMenuPanel = false;
        break;
        case "2":
         this.loadChildNodesFromRemoteServer(this.currentNode.text,(data)=>{
          console.log("vvvv",data)
          if(data){
          this.$refs.graphRef.getInstance().appendJsonData(data, (graphInstance) => {
          // 这些写上当图谱初始化完成后需要执行的代码
          this.$refs.graphRef.refresh();
          
        });
      }
    });

                      
       
        break;
      }
      
    },
    doFilter() {
      const _all_nodes = this.$refs.graphRef.getInstance().getNodes();
      const _all_links = this.$refs.graphRef.getInstance().getLinks();
      _all_nodes.forEach((thisNode) => {
        let _isHideThisLine = false;
        if (this.checked_sex !== "") {
          if (thisNode.data["sexType"] !== this.checked_sex) {
            _isHideThisLine = true;
          }
        }
        if (this.checked_isgoodman !== "") {
          if (thisNode.data["isGoodMan"] !== this.checked_isgoodman) {
            _isHideThisLine = true;
          }
        }
        thisNode.opacity = _isHideThisLine ? 0.1 : 1;
      });
      _all_links.forEach((thisLink) => {
        thisLink.relations.forEach((thisLine) => {
          if (this.rel_checkList.indexOf(thisLine.data["type"]) === -1) {
            if (!thisLine.isHide) {
              thisLine.isHide = true;
              console.log("Hide line:", thisLine);
            }
          } else {
            if (thisLine.isHide) {
              thisLine.isHide = false;
              console.log("Show line:", thisLine);
            }
          }
        });
        // thisNode.opacity = _isShowThisNode ? 1 : 0.1
      });
      this.$refs.graphRef.getInstance().dataUpdated();
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="css" scoped>
.my-node-style {
  background-position: center center;
  background-size: 100%;
  height: 100%;
  width: 100%;
  border-radius: 50%;
  overflow: visible;
}
.c-node-name {
  width: 80px;
  text-align: center;
  color: #2e74b5;
  /* margin-top: 10px; */
}
.c-my-rg-node {
   height: 100%;
  line-height:100%; 
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  place-items: center;
  justify-content: center;
}
.c-node-menu-item {
  line-height: 30px;
  padding-left: 10px;
  cursor: pointer;
  color: #444444;
  font-size: 14px;
  border-top: #efefef solid 1px;
}
.c-node-menu-item:hover {
  background-color: rgba(66, 187, 66, 0.2);
}

.c-my-panel {
  position: absolute;
  left: 10px;
  top: 100px;
  border-radius: 10px;
  z-index: 800;
  background-color: #efefef;
  border: #eeeeee solid 1px;
  padding: 20px;
}
.c-option-name {
  color: #666666;
  font-size: 14px;
  line-height: 40px;
  padding-left: 10px;
  padding-right: 10px;
}
.my-node-1 {
  height: 100%;
  cursor: pointer;
  display: flex;
  place-items: center;
  justify-content: center;

}
.my-node-text {
    color: #666666;
    font-size: 16px;
    position: absolute;
    border-radius: 10px;
    width: 160px;
    height:25px;
    line-height: 25px;
    margin-top:calc(100% + 20px);
    margin-left:0px;
    text-align: center;
   
  }
</style>
